<template>
	<div>

		<!-- 添加角色按钮 -->
		<el-button style="margin-bottom: 20px;" size="small" type="primary" icon="el-icon-plus" @click="editRole(false)">添加角色</el-button>
		<!-- 角色列表 -->
		<el-table :data="roles" v-loading="loading">
			<el-table-column label="角色名称" prop="name" align="center"></el-table-column>
			<el-table-column label="管理员数量" align="center" :formatter="row => row.adminCount + '人'"></el-table-column>
			<el-table-column label="创建时间" prop="createTime" align="center"></el-table-column>
			<el-table-column label="操作" align="center">
				<template slot-scope="scope">
					<el-button type="text" size="small" icon="el-icon-menu" @click="configMenu(scope.row)">配置菜单</el-button>
					<el-button type="text" size="small" icon="el-icon-link" @click="configPermission(scope.row)">配置权限</el-button>
					<el-button type="text" size="small" icon="el-icon-edit-outline" @click="editRole(scope.row)">编辑名称</el-button>
					<el-button type="text" size="small" icon="el-icon-delete" @click="deleteRole(scope.row)">删除</el-button>
				</template>
			</el-table-column>
		</el-table>

		<!-- 配置菜单面板 -->
		<!-- <el-dialog :title="`${role.id == 1 ? `${role.name}的菜单` : `为${role.name}配置菜单`}`" :visible.sync="showMenuPanel" width="30vw">
			<el-tree :load="loadMenus" lazy :show-checkbox="role.id != 1" default-expand-all check-on-click-node node-key="id"
			 @check="onMenusChange" ref="menuTree"></el-tree>

			<span slot="footer" v-if="role.id != 1 && checkedMenuIds.length > 0">
				<el-button size="medium" @click="showMenuPanel = false">取 消</el-button>
				<el-button size="medium" type="primary" @click="confrimMenus">确 定</el-button>
			</span>
		</el-dialog> -->

		<el-drawer :title="`${role.id == 1 ? `${role.name}的菜单` : `为${role.name}配置菜单`}`" :visible.sync="showMenuPanel"
		 direction="ltr">
			<div class="menus-wrap">
				<el-tree :load="loadMenus" lazy :show-checkbox="role.id != 1" default-expand-all check-on-click-node node-key="id"
				 @check="onMenusChange" ref="menuTree"></el-tree>

				<div class="btn-wrap" v-if="role.id != 1 && checkedMenuIds.length > 0">
					<el-button size="medium" @click="showMenuPanel = false">取 消</el-button>
					<el-button size="medium" type="primary" @click="confrimMenus">确 定</el-button>
				</div>
			</div>
		</el-drawer>

		<!-- 配置接口面板 -->
		<el-dialog :title="`${role.id == 1 ? `${role.name}的权限` : `为${role.name}配置权限`}`" :visible.sync="showPermissionPanel"
		 fullscreen>
			<div class="permission-wrap">
				<div class="permission" v-for="(item, index) in permissions" :key="index">
					<div class="controller">
						<span class="name">{{item.name}}</span>
						<el-switch active-text="全选" :disabled="role.id == 1" :value="role.id == 1 || item.checked" @change="batchUpdatePermission($event, item, index)"></el-switch>
					</div>
					<div class="keys">
						<div class="item" v-for="(key, keyIndex) in item.list" :key="keyIndex">
							<el-switch :disabled="role.id == 1" :value="role.id == 1 || key.checked" @change="updatePermission($event, key, item, index)"></el-switch>
							<span class="name">{{key.actionKey}}</span>
							<span class="remark">{{key.remark}}</span>
						</div>
					</div>
				</div>
			</div>
		</el-dialog>

	</div>
</template>

<script>
	export default {
		data() {
			return {
				roles: [],
				loading: false,
				role: {},
				showMenuPanel: false,
				permissions: [],
				showPermissionPanel: false,
				checkedMenuIds: []
			}
		},
		created() {
			this.findRoles();
		},
		methods: {
			findRoles() {
				this.loading = true;
				this.$util.request('/role', {}, (res) => {
					this.loading = false;
					this.roles = res;
				}, true);
			},
			editRole(item) {
				this.$prompt('输入角色名称', '', {
					inputValue: item ? item.name : '',
					inputValidator(val) {
						if (!val.trim()) return '请输入角色名称';
					}
				}).then(res => {
					const loading = this.$loading({
						text: '处理中...'
					});
					this.$util.request('/role/' + (item ? 'updateName' : 'save'), {
						id: item ? item.id : '',
						name: res.value
					}, (res) => {
						loading.close();

						if (res.state == 'ok') {
							this.$message.success('操作成功');
							this.findRoles();
						} else {
							this.$util.msg(res.msg);
						}
					});
				}).catch(_ => {});
			},
			deleteRole(item) {
				this.$util.requestWithConfirm(`确定删除【${item.name}】吗？`, '/role/delete', {
					id: item.id
				}).then(_ => {
					this.findRoles();
				});
			},
			configMenu(item) {
				this.role = item;
				this.showMenuPanel = true;

				if (item.id != 1) {
					this.checkedMenuIds = [];
					// 加载当前角色已选中的菜单
					const loading = this.$loading({
						text: '加载中...'
					});
					this.$util.request('/menu/menusOfRole', {
						roleId: item.id
					}, (res) => {
						loading.close();
						this.$refs.menuTree.setCheckedKeys(res);
					}, true);
				}
			},
			loadMenus(node, resolve) {
				this.$util.request('/menu/all', {
					parentId: node.data ? node.data.id : 0
				}, (res) => {
					resolve(res.map(e => {
						return {
							id: e.id,
							label: e.name,
							isLeaf: e.parentId != 0
						};
					}));
				}, true);
			},
			onMenusChange(node, checkedState) {
				this.checkedMenuIds = checkedState.checkedKeys.concat(checkedState.halfCheckedKeys);
			},
			confrimMenus() {
				this.$util.request('/role/updateMenus', {
					roleId: this.role.id,
					menuIds: this.checkedMenuIds.join(',')
				}, (res) => {
					if (res.state == 'ok') {
						this.$message.success('操作成功');
						this.showMenuPanel = false;
					} else {
						this.$util.msg(res.msg);
					}
				});
			},
			configPermission(item) {
				this.role = item;
				this.showPermissionPanel = true;

				this.loadPermissions().then(_ => {
					if (item.id != 1) {
						// 加载当前角色的已选中权限
						const loading = this.$loading({
							text: '加载中...'
						});
						this.$util.request('/permission/permissionsOfRole', {
							roleId: item.id
						}, (res) => {
							loading.close();

							this.permissions.forEach(e => {
								let count = 0;
								e.list.forEach(key => {
									if (res.includes(key.id)) {
										count++;
										key.checked = true;
									} else {
										key.checked = false;
									}
								});
								e.checked = count == e.list.length;
							});
							this.$forceUpdate();
						}, true);
					}
				});
			},
			loadPermissions() {
				return new Promise(resolve => {
					if (this.permissions.length == 0) {
						const loading = this.$loading({
							text: '加载中...'
						});
						this.$util.request('/permission', {
							pageSize: 500
						}, (res) => {
							res = res.list;
							// 获取全部控制器
							let controllers = new Set();
							res.forEach(e => {
								controllers.add(e.controller);
							});
							// 获取每个控制器下的接口列表
							this.permissions = Array.from(controllers).map(e => {
								return {
									name: e,
									list: res.filter(key => key.controller == e)
								}
							});
							loading.close();
							resolve();
						}, true);
					} else {
						resolve();
					}
				});
			},
			batchUpdatePermission(checked, item, index) {
				// 获取和当前全选按钮状态不一致的权限
				const keys = item.list.filter(e => e.checked != checked);
				// 分别更新状态
				keys.forEach(key => {
					this.updatePermission(checked, key, item, index);
				});
			},
			updatePermission(checked, key, item, index) {
				const loading = this.$loading();
				this.$util.request('/role/updatePermission', {
					roleId: this.role.id,
					permissionId: key.id
				}, (res) => {
					loading.close();

					if (res.state == 'ok') {
						key.checked = checked;
						item.checked = item.list.length == item.list.filter(e => e.checked).length;
						this.$set(this.permissions, index, this.permissions[index]);
					} else {
						this.$util.msg(res.msg);
					}
				});
			}
		}
	}
</script>

<style lang="scss">
	.menus-wrap {
		padding: 20px;
		position: relative;
		max-height: 100%;
		overflow-y: auto;

		.btn-wrap {
			margin-top: 20px;
		}
	}

	.permission-wrap {
		display: flex;
		flex-wrap: wrap;

		.permission {
			color: #333;
			margin: 10px;

			.controller {

				.name {
					font-weight: bold;
					margin-right: 10px;
				}
			}

			.keys {

				.item {
					line-height: 2.4;

					.name {
						margin: 0 10px;
					}

					.remark {
						color: gray;
					}
				}
			}
		}
	}
</style>
